package org.model.common.handler;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.model.common.exception.ServiceException;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 动态表处理器.
 *
 * @author Luo
 * @date 2023-08-03 9:57
 */
@Slf4j
public class ShardTableHandler {

    /**
     * 判断表是否存在.
     */
    private static final String TABLE_IS_EXIST = "SELECT COUNT(*) FROM information_schema.tables WHERE table_name = ?";

    private final JdbcTemplate jdbcTemplate;

    public ShardTableHandler(final JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    /**
     * 创建表.
     *
     * @param tableName   表名
     * @param sqlFilePath 建表SQL文件路径
     */
    public void createTable(final String tableName, final String sqlFilePath) {
        // 判断表是否存在
        Integer query = jdbcTemplate.queryForObject(TABLE_IS_EXIST, Integer.class, tableName);
        if (Objects.nonNull(query) && query > 0) {
            log.info("创建表时[tableName = {}]已经存在", tableName);
            return;
        }
        String createTableSql;
        try {
            // 获取文件的URL
            InputStream inputStream = getClass().getClassLoader().getResourceAsStream(sqlFilePath);
            if (inputStream == null) {
                throw new FileNotFoundException("建表文件未找到");
            }
            // 将InputStream内容转换为String
            String content = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))
                    .lines()
                    .collect(Collectors.joining(System.lineSeparator()));
            // 获取建表SQL
            createTableSql = String.format(content, tableName);
        } catch (Exception e) {
            log.error("创建表[tableName = {}]读取建表语句异常：{}", tableName, ExceptionUtils.getStackTrace(e));
            throw new ServiceException("读取建表语句异常");
        }
        try {
            // 执行建表语句
            jdbcTemplate.execute(createTableSql);
        } catch (DataAccessException e) {
            log.error("执行创建表语句[tableName = {}]异常：{}", tableName, ExceptionUtils.getStackTrace(e));
            throw new ServiceException("执行建表语句异常");
        }
    }

}
